package org.ftc.service;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.ftc.dao.InChargeDao;
import org.ftc.dao.UsersDao;
import org.ftc.domain.InCharge;
import org.ftc.domain.Users;
import org.ftc.service.FtcLogService.Log;
import org.ftc.service.UsersService.TypeCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.util.HtmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

@Service
public class LoadUserDataTaskService {

	@Autowired
	FtcLogService logService;
	@Autowired
	UsersDao usersDao;
	@Autowired
	InChargeDao inChargeDao;
	private final String USER_AGENT = "Mozilla/5.0";

	// HTTP POST request
	private String sendPost(String queryType, String id, String pw) throws Exception {
		logService.before();
		// String url = "http://nt8apsvr14.ftc.gov.tw/ws/test.aspx";

		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost("http://nt8apsvr14.ftc.gov.tw/ws/test.aspx");

		// add header
		post.setHeader("User-Agent", USER_AGENT);
		List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
		urlParameters
				.add(new BasicNameValuePair(
						"__VIEWSTATE",
						"/wEPDwUJNjUxMjExNDU0ZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAgUKcXVlcnlUeXBlMQUKcXVlcnlUeXBlMpXvsdaMJhplla9octwAGwgF+8G4JLVvpr3i1f1RhIlk"));
		urlParameters
				.add(new BasicNameValuePair("__EVENTVALIDATION",
						"/wEWBwK1uNSZBwKk8pXKBgKl8pXKBgLq0Oe3CwLGmdGVDALCi9reAwKrkaXBAU614Hq21wZzI8HBtJCfMFdnJEbgb07YW+bb0poyV5G4"));
		urlParameters.add(new BasicNameValuePair("queryType", StringUtils.equals(queryType, "2") ? "2" : "1"));
		urlParameters.add(new BasicNameValuePair("empNo", StringUtils.equals(queryType, "2") ? "ipotent" : id));
		urlParameters.add(new BasicNameValuePair("pwd", StringUtils.equals(queryType, "2") ? "ipo@tent123" : pw));
		urlParameters.add(new BasicNameValuePair("btnSubmit", "Query"));
		post.setEntity(new UrlEncodedFormEntity(urlParameters));
		HttpResponse response = client.execute(post);
		logService.save(Log.QUERY, response.getStatusLine().getStatusCode() + "", this.getClass().toString());
		BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
		StringBuffer result = new StringBuffer();
		String line = "";
		while ((line = rd.readLine()) != null) {
			result.append(line);
		}
		return result.toString();
	}

	public boolean checkUser(String id, String pw) {
		boolean valid= false;
		try {
			String result = sendPost("1", id, pw);

			String escapeStr = HtmlUtils.htmlUnescape(result);

			String finalStr = StringUtils.substringBetween(escapeStr, "rows=\"20\">", "</textarea>");
			ByteArrayInputStream stream = new ByteArrayInputStream(finalStr.getBytes("UTF-8"));
			Document document = convertStringToDocument(stream);
			NodeList nodeList = document.getDocumentElement().getChildNodes();
			for (int i = 0; i < nodeList.getLength(); i++) {
				Node node = nodeList.item(i);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					if (StringUtils.equals(node.getNodeName(), "CODE")) {
						if (StringUtils.equals(node.getTextContent(), "0")) {
							valid = true;
						}
					}
				}
			}
		} catch (Exception e) {
			return false;
		}
		return valid;
	}

	/**
	 * 應只帶出dept_code 1、2開頭
	 * @return
	 * @throws ParserConfigurationException
	 * @throws MalformedURLException
	 * @throws SAXException
	 * @throws IOException
	 */
	public boolean update() throws ParserConfigurationException, MalformedURLException, SAXException, IOException {
		String result = "";
		try {
			result = sendPost("2", "", "");
		} catch (Exception e) {
			e.printStackTrace();
		}
		String escapeStr = HtmlUtils.htmlUnescape(result);

		String finalStr = StringUtils.substringBetween(escapeStr, "rows=\"20\">", "</textarea>");
		ByteArrayInputStream stream = new ByteArrayInputStream(finalStr.getBytes("UTF-8"));
		Document document = convertStringToDocument(stream);

		List<Users> users = new ArrayList<>();
		Map<String, Users> map = new HashMap<>();
		NodeList nodeList = document.getDocumentElement().getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			NodeList nodeList2 = node.getChildNodes();
			for (int j = 0; j < nodeList2.getLength(); j++) {
				Node node2 = nodeList2.item(j);
				NodeList nodeList3 = node2.getChildNodes();
				for (int k = 0; k < nodeList3.getLength(); k++) {
					Node node3 = nodeList3.item(k);
					if (node3.getNodeType() == Node.ELEMENT_NODE) {
						Element elem = (Element) node3;
						Users user = new Users();
						String code = genSource(elem, "CODE");
						if (!StringUtils.equals(code, "0")) {
							continue;
						}
						String status = genSource(elem, "STATUS");
						String deptCode = genSource(elem, "DEPT_CODE");
						String deptName = genSource(elem, "DEPT_NAME");
						String unitCode = genSource(elem, "UNIT_CODE");
						String unitName = genSource(elem, "UNIT_NAME");
						String cName = genSource(elem, "C_NAME");
						String title = genSource(elem, "TITLE");
						String decLevel = genSource(elem, "DEC_LEVEL");
						String email = genSource(elem, "EMAIL");
						String empCode = genSource(elem, "EMP_CODE");
						String telephone = genSource(elem, "TELEPHONE");
						String telNo = genSource(elem, "TEL_EXT");
						String mainEmpNo = genSource(elem, "MAIN_EMP_NO");
						String userId = genSource(elem, "USER_ID");
						user.setStatus2(status);
						user.setDeptCode(deptCode);
						user.setDeptName(deptName);
						user.setUnitCode(unitCode);
						user.setUnitName(unitName);
						user.setName(cName);
						user.setTitle(title);
						user.setDecLevel(decLevel);
						user.setEmail(email);
						user.setEmpCode(empCode);
						user.setTelephone(telephone);
						user.setExt(telNo);
						user.setUserName(userId);
						users.add(user);
						if (StringUtils.equals(title, "科長")) {
							map.put(unitCode, user);
						}
					}
				}
			}
		}
		// Print all employees.
		for (Users user : users) {
			logService.before();
			Users dbUser = usersDao.findByUserName(user.getUserName());
			if (dbUser == null) {
				user.setStatus(0);
				user.setCreationDate(new Date());
				user.setType(TypeCode.USERS.toString());
				usersDao.save(user);
				logService.save(Log.INSERT, user.getUsersSeq(), this.getClass().toString());
			} else {
				if (!compareUsers(user, dbUser)) {
					user.setStatus(dbUser.getStatus());
					user.setRole(dbUser.getRole());
					user.setType(TypeCode.USERS.toString());
					user.setCreationDate(new Date());
					usersDao.save(user);
					dbUser.setStatus2("1");
					dbUser.setStatus(0);
					dbUser.setCreationDate(new Date());
					usersDao.update(dbUser);
					logService.save(Log.INSERT, user.getUsersSeq(), this.getClass().toString());
				}
			}
			Users chief = map.get(user.getUnitCode());
			InCharge old = inChargeDao.findByUserId(user.getUserName());
			if (chief != null && StringUtils.equals(user.getDecLevel(), "4") && StringUtils.isNotBlank(user.getExt())) {
				InCharge ic = new InCharge();
				ic.setTelNo(user.getExt());
				ic.setUserId(user.getUserName());
				ic.setName(StringUtils.equals(chief.getName(), user.getName()) ? "" : user.getName());
				ic.setSectionChief(chief.getName());
				ic.setStatus(user.getStatus2());
				if (old == null) {
					inChargeDao.save(ic);
					logService.save(Log.INSERT, user.getUsersSeq(), this.getClass().toString());
				} else {
					if (!compareInCharge(ic, old)) {
						old.setStatus("1");
						inChargeDao.update(old);
						inChargeDao.save(ic);
						logService.save(Log.INSERT, user.getUsersSeq(), this.getClass().toString());
					}
				}

			}
		}
		return true;
	}

	private static Document convertStringToDocument(ByteArrayInputStream stream) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			Document doc = builder.parse(stream);
			return doc;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private String genSource(Element elem, String colName) {
		return elem.getElementsByTagName(colName).item(0).getTextContent();
	}

	private boolean compareUsers(Users user1, Users user2) {
		boolean result = true;

		if (!StringUtils.equals(user1.getName(), user2.getName())) {
			return false;
		}
		if (!StringUtils.equals(user1.getDeptCode(), user2.getDeptCode())) {
			return false;
		}
		if (!StringUtils.equals(user1.getDeptName(), user2.getDeptName())) {
			return false;
		}
		if (!StringUtils.equals(user1.getUnitCode(), user2.getUnitCode())) {
			return false;
		}
		if (!StringUtils.equals(user1.getUnitName(), user2.getUnitName())) {
			return false;
		}
		if (!StringUtils.equals(user1.getTitle(), user2.getTitle())) {
			return false;
		}
		if (!StringUtils.equals(user1.getEmail(), user2.getEmail())) {
			return false;
		}
		if (!StringUtils.equals(user1.getEmpCode(), user2.getEmpCode())) {
			return false;
		}
		if (!StringUtils.equals(user1.getDecLevel(), user2.getDecLevel())) {
			return false;
		}
		if (!StringUtils.equals(user1.getTelephone(), user2.getTelephone())) {
			return false;
		}
		if (!StringUtils.equals(user1.getExt(), user2.getExt())) {
			return false;
		}
		if (!StringUtils.equals(user1.getStatus2(), user2.getStatus2())) {
			return false;
		}
		return result;
	}

	private boolean compareInCharge(InCharge user1, InCharge user2) {
		boolean result = true;

		if (!StringUtils.equals(user1.getName(), user2.getName())) {
			return false;
		}
		if (!StringUtils.equals(user1.getSectionChief(), user2.getSectionChief())) {
			return false;
		}
		if (!StringUtils.equals(user1.getTelNo(), user2.getTelNo())) {
			return false;
		}
		if (!StringUtils.equals(user1.getStatus(), user2.getStatus())) {
			return false;
		}
		return result;
	}

	public static void main(String[] args) throws Exception {
		String str = "<td align=\"left\" valign=\"top\"><textarea name=\"result\" id=\"result\" cols=\"65\" rows=\"20\">?&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;&lt;DATA&gt;  &lt;DEPT NAME=&quot;主委室&quot; CODE=&quot;010&quot;&gt;    &lt;USERS&gt;      &lt;USER&gt;        &lt;CODE&gt;0&lt;/CODE&gt;        &lt;DEPT_CODE&gt;010&lt;/DEPT_CODE&gt;        &lt;DEPT_NAME&gt;主委室&lt;/DEPT_NAME&gt;        &lt;UNIT_CODE&gt;&lt;/UNIT_CODE&gt;        &lt;UNIT_NAME&gt;&lt;/UNIT_NAME&gt;        &lt;C_NAME&gt;許淑芬&lt;/C_NAME&gt;        &lt;TITLE&gt;登記桌&lt;/TITLE&gt;        &lt;DEC_LEVEL&gt;4&lt;/DEC_LEVEL&gt;        &lt;EMAIL&gt;&lt;/EMAIL&gt;        &lt;EMP_CODE&gt;0359&lt;/EMP_CODE&gt;        &lt;TELEPHONE&gt;23517588&lt;/TELEPHONE&gt;        &lt;TEL_EXT&gt;104&lt;/TEL_EXT&gt;        &lt;STATUS&gt;0&lt;/STATUS&gt;        &lt;MAIN_EMP_NO&gt;&lt;/MAIN_EMP_NO&gt;        &lt;USER_ID&gt;100734960&lt;/USER_ID&gt;      &lt;/USER&gt;  &lt;/USERS&gt;&lt;/DEPT&gt;&lt;/DATA&gt;</textarea>";
		String xx = StringUtils.substringBetween(str, "\">?", "</textarea>");
		System.out.println(xx);
		System.out.println(HtmlUtils.htmlUnescape(xx));
		LoadUserDataTaskService x = new LoadUserDataTaskService();
		System.out.println(StringEscapeUtils.escapeJava("<td align=\"left\""));
		System.out.println("<td align=\"left\"");
		// x.update();
		// x.sendPost();
		// System.out.println(StringEscapeUtils.escapeHtml4("<script>alert('xxxx');</script>"));
	}
}